﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace AnimationEditor
{
	enum EditorTool { Frame, Anchor, Collision, Point };

	public partial class MainForm : Form
	{
		Bitmap spriteSheet = null;
		Bitmap spriteSheetScale = null;
		Bitmap spriteSheetAlpha = null;
		List<Frame> masterListFrames = new List<Frame>();

		List<Rectangle> masterListCollision = new List<Rectangle>();
		List<Point> masterListPoints = new List<Point>();

		EditorTool tool = EditorTool.Frame;
		Point frameStart = new Point();
		Point frameEnd = new Point();

		Point collisionStart = new Point();
		Point collisionEnd = new Point();

		bool updateConstantly = false;

		float currentZoom = 1.0f;

		public MainForm()
		{
			InitializeComponent();

			toolStripComboBoxZoom.SelectedIndex = 3;
		}

		private void Clear()
		{
			spriteSheet = null;
			spriteSheetAlpha = null;

			masterListFrames.Clear();

			textBoxFrameName.Text = "DEFAULT";

			textBoxFrameEvent.Text = "";

			numericUpDownSpeed.Value = 0.125m;

			numericUpDownFrameX.Value = 0;
			numericUpDownFrameY.Value = 0;
			numericUpDownFrameWidth.Value = 0;
			numericUpDownFrameHeight.Value = 0;

			numericUpDownAnchorX.Value = 0;
			numericUpDownAnchorY.Value = 0;

			numericUpDownCollisionX.Value = 0;
			numericUpDownCollisionY.Value = 0;
			numericUpDownCollisionWidth.Value = 0;
			numericUpDownCollisionHeight.Value = 0;

			masterListCollision.Clear();
			listBoxCollision.DataSource = null;
			listBoxCollision.DataSource = masterListCollision;

			numericUpDownPointX.Value = 0;
			numericUpDownPointY.Value = 0;

			masterListPoints.Clear();
			listBoxPoints.DataSource = null;
			listBoxPoints.DataSource = masterListPoints;


			listBoxFrames.DataSource = null;
			listBoxFrames.DataSource = masterListFrames;

			listBoxFrames.SelectedIndex = -1;

			graphicsPanelSpriteSheet.Invalidate();
			graphicsPanelAnimationPreview.Invalidate();
		}

		private Bitmap ScaleImage(Bitmap image, float scale)
		{
			int sourceWidth = image.Width;
			int sourceHeight = image.Height; 
			int destWidth = (int)(sourceWidth * scale);
			int destHeight = (int)(sourceHeight * scale);

			Bitmap bitmap = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);

			//bitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution);

			Graphics photo = Graphics.FromImage(bitmap);
			//photo.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

			photo.DrawImage(image,
							new System.Drawing.Rectangle(0, 0, destWidth, destHeight),
							new System.Drawing.Rectangle(0, 0, sourceWidth, sourceHeight),
							GraphicsUnit.Pixel);

			photo.Dispose();

			return bitmap;
		}

		private void toolStripMenuItemUpdateConstantly_Click(object sender, EventArgs e)
		{
			((ToolStripMenuItem)sender).Checked = !((ToolStripMenuItem)sender).Checked;

			updateConstantly = !updateConstantly;
		}

		private void toolStripMenuItemSpriteSheet_Click(object sender, EventArgs e)
		{
			OpenFileDialog file = new OpenFileDialog();

			if (file.ShowDialog() == DialogResult.OK)
			{
				spriteSheet = new Bitmap(file.FileName);

				spriteSheetScale = new Bitmap(spriteSheet);

				spriteSheetAlpha = new Bitmap(spriteSheet);
				for (int x = 0; x < spriteSheetAlpha.Width; ++x)
				{
					for (int y = 0; y < spriteSheetAlpha.Height; ++y)
					{
						Color oldcolor = spriteSheetAlpha.GetPixel(x, y);

						Color newcolor = Color.FromArgb(75, oldcolor);

						spriteSheetAlpha.SetPixel(x, y, newcolor);
					}
				}

				toolStripComboBoxZoom.SelectedIndex = 3;

				graphicsPanelSpriteSheet.Invalidate();
			}
		}

		private void toolStripMenuItemNew_Click(object sender, EventArgs e)
		{
			if (MessageBox.Show("Are you sure you want to make a new animation (all current information will be gone)", "New", MessageBoxButtons.YesNo) == DialogResult.Yes)
			{
				Clear();
			}
		}

		private void toolStripMenuItemSave_Click(object sender, EventArgs e)
		{
			SaveFileDialog dlg = new SaveFileDialog();

			dlg.DefaultExt = "wya";

			dlg.Filter = "Why Animation(*.wya)|*.myf|All Files(*.*)|*.*";

			dlg.AddExtension = true;

			if ( DialogResult.OK == dlg.ShowDialog() )
			{
				FileStream stream = new FileStream(dlg.FileName, FileMode.Create);

				BinaryWriter writer = new BinaryWriter(stream);

				writer.Write((int)masterListFrames.Count);

				foreach (Frame frame in masterListFrames)
				{
					writer.Write((string)frame.Name);

					writer.Write((string)frame.Eventstring);

					writer.Write((double)frame.Speed);

					writer.Write((int)frame.FrameRect.X);
					writer.Write((int)frame.FrameRect.Y);
					writer.Write((int)frame.FrameRect.Width);
					writer.Write((int)frame.FrameRect.Height);

					writer.Write((int)frame.AnchorPoint.X);
					writer.Write((int)frame.AnchorPoint.Y);

					writer.Write((int)frame.CollisionRects.Count);

					foreach (Rectangle rect in frame.CollisionRects)
					{
						writer.Write((int)rect.X);
						writer.Write((int)rect.Y);
						writer.Write((int)rect.Width);
						writer.Write((int)rect.Height);
					}

					writer.Write((int)frame.SpecialPoints.Count);

					foreach (Point point in frame.SpecialPoints)
					{
						writer.Write((int)point.X);
						writer.Write((int)point.Y);
					}

				}

				writer.Close();
			}
			
		}

		private void toolStripMenuItemOpen_Click(object sender, EventArgs e)
		{
			OpenFileDialog dlg = new OpenFileDialog();

			dlg.DefaultExt = "wya";

			dlg.Filter = "Why Animation(*.wya)|*.myf|All Files(*.*)|*.*";

			if (DialogResult.OK == dlg.ShowDialog())
			{
				Clear();

				FileStream stream = new FileStream(dlg.FileName, FileMode.Open);

				BinaryReader reader = new BinaryReader(stream);

				int frameCount = reader.ReadInt32();

				for(int i = 0; i < frameCount; ++i)
				{
					Frame newframe = new Frame();

					newframe.Name = reader.ReadString();

					newframe.Eventstring = reader.ReadString();

					newframe.Speed = reader.ReadDouble();

					newframe.FrameRect.X = reader.ReadInt32();
					newframe.FrameRect.Y = reader.ReadInt32();
					newframe.FrameRect.Width = reader.ReadInt32();
					newframe.FrameRect.Height = reader.ReadInt32();

					newframe.AnchorPoint.X = reader.ReadInt32();
					newframe.AnchorPoint.Y = reader.ReadInt32();

					int collisionCount = reader.ReadInt32();

					for (int j = 0; j < collisionCount; ++j)
					{
						Rectangle rect = new Rectangle();

						rect.X = reader.ReadInt32();
						rect.Y = reader.ReadInt32();
						rect.Width = reader.ReadInt32();
						rect.Height = reader.ReadInt32();

						newframe.CollisionRects.Add(rect);
					}

					int specialPointsCount = reader.ReadInt32();

					for (int j = 0; j < specialPointsCount; ++j)
					{
						Point point = new Point();

						point.X = reader.ReadInt32();
						point.Y = reader.ReadInt32();

						newframe.SpecialPoints.Add(point);
					}

					masterListFrames.Add(newframe);

					listBoxFrames.DataSource = null;
					listBoxFrames.DataSource = masterListFrames;

				}

				reader.Close();
			}
		}

		private void toolStripButtonFrameTool_Click(object sender, EventArgs e)
		{
			tool = EditorTool.Frame;

			for (int i = 0; i < toolStripSpriteSheet.Items.Count; ++i)
			{
				if (toolStripSpriteSheet.Items[i] is ToolStripButton)
				{
					((ToolStripButton)toolStripSpriteSheet.Items[i]).Checked = false;
				}
			}

			((ToolStripButton)sender).Checked = true;
		}

		private void toolStripButtonCollisionTool_Click(object sender, EventArgs e)
		{
			tool = EditorTool.Collision;

			for (int i = 0; i < toolStripSpriteSheet.Items.Count; ++i)
			{
				if (toolStripSpriteSheet.Items[i] is ToolStripButton)
				{
					((ToolStripButton)toolStripSpriteSheet.Items[i]).Checked = false;
				}
			}

			((ToolStripButton)sender).Checked = true;
		}

		private void toolStripButtonAnchorTool_Click(object sender, EventArgs e)
		{
			tool = EditorTool.Anchor;

			for (int i = 0; i < toolStripSpriteSheet.Items.Count; ++i)
			{
				if (toolStripSpriteSheet.Items[i] is ToolStripButton)
				{
					((ToolStripButton)toolStripSpriteSheet.Items[i]).Checked = false;
				}
			}

			((ToolStripButton)sender).Checked = true;
		}

		private void toolStripButtonPointTool_Click(object sender, EventArgs e)
		{
			tool = EditorTool.Point;

			for (int i = 0; i < toolStripSpriteSheet.Items.Count; ++i)
			{
				if (toolStripSpriteSheet.Items[i] is ToolStripButton)
				{
					((ToolStripButton)toolStripSpriteSheet.Items[i]).Checked = false;
				}
			}

			((ToolStripButton)sender).Checked = true;
		}

		private void checkBoxOnionSkin_CheckedChanged(object sender, EventArgs e)
		{
			graphicsPanelAnimationPreview.Invalidate();
		}

		private void graphicsPanelSpriteSheet_Paint(object sender, PaintEventArgs e)
		{
			if (spriteSheet == null)
				return;

			System.Drawing.Point draw = new System.Drawing.Point(0, 0);
			draw.X += graphicsPanelSpriteSheet.AutoScrollPosition.X;
			draw.Y += graphicsPanelSpriteSheet.AutoScrollPosition.Y;

			e.Graphics.DrawImage(spriteSheetScale, draw);

			Pen framePen = new Pen(Color.Orange, 2);

			e.Graphics.DrawRectangle(framePen,
				(int)numericUpDownFrameX.Value * currentZoom + draw.X,
				(int)numericUpDownFrameY.Value * currentZoom + draw.Y,
				(int)numericUpDownFrameWidth.Value * currentZoom,
				(int)numericUpDownFrameHeight.Value * currentZoom);

			Pen collisionPen = new Pen(Color.HotPink, 2);

			e.Graphics.DrawRectangle(collisionPen,
				(int)numericUpDownCollisionX.Value * currentZoom + draw.X,
				(int)numericUpDownCollisionY.Value * currentZoom + draw.Y,
				(int)numericUpDownCollisionWidth.Value * currentZoom,
				(int)numericUpDownCollisionHeight.Value * currentZoom);

			e.Graphics.FillEllipse(Brushes.Blue,
				(int)numericUpDownAnchorX.Value * currentZoom - 6 + draw.X,
				(int)numericUpDownAnchorY.Value * currentZoom - 6 + draw.Y,
				12, 12);

			e.Graphics.FillEllipse(Brushes.DarkGreen,
				(int)numericUpDownPointX.Value * currentZoom - 6 + draw.X,
				(int)numericUpDownPointY.Value * currentZoom - 6 + draw.Y,
				12, 12);
		}

		private void graphicsPanelAnimationPreview_Paint(object sender, PaintEventArgs e)
		{
			if (spriteSheet == null)
				return;

			if (listBoxFrames.SelectedIndex == -1)
				return;

			Frame frame = (Frame)listBoxFrames.SelectedItem;
			Frame nextframe;

			if (listBoxFrames.SelectedIndex + 1 >= listBoxFrames.Items.Count)
			{
				nextframe = (Frame)listBoxFrames.Items[0];
			}
			else
			{
				nextframe = (Frame)listBoxFrames.Items[listBoxFrames.SelectedIndex + 1];
			}

			e.Graphics.DrawImage(spriteSheet,
				(graphicsPanelAnimationPreview.Size.Width / 2) + (frame.FrameRect.X - frame.AnchorPoint.X),
				(graphicsPanelAnimationPreview.Size.Height / 2) + (frame.FrameRect.Y - frame.AnchorPoint.Y),
				new System.Drawing.Rectangle(frame.FrameRect.X, frame.FrameRect.Y, frame.FrameRect.Width, frame.FrameRect.Height), GraphicsUnit.Pixel);

			if (checkBoxOnionSkin.Checked == true)
			{
				e.Graphics.DrawImage(spriteSheetAlpha,
					(graphicsPanelAnimationPreview.Size.Width / 2) + (nextframe.FrameRect.X - nextframe.AnchorPoint.X),
					(graphicsPanelAnimationPreview.Size.Height / 2) + (nextframe.FrameRect.Y - nextframe.AnchorPoint.Y),
					new System.Drawing.Rectangle(nextframe.FrameRect.X, nextframe.FrameRect.Y, nextframe.FrameRect.Width, nextframe.FrameRect.Height), GraphicsUnit.Pixel);
			}
		}

		private void graphicsPanelSpriteSheet_MouseDown(object sender, MouseEventArgs e)
		{
			if (spriteSheet == null)
				return;

			System.Drawing.Point read = new System.Drawing.Point(0, 0);
			read.X += graphicsPanelSpriteSheet.AutoScrollPosition.X;
			read.Y += graphicsPanelSpriteSheet.AutoScrollPosition.Y;

			Point mouse = new Point(
				(int)((e.X - read.X) / currentZoom),
				(int)((e.Y - read.Y) / currentZoom));

			if (mouse.X < 0 || mouse.Y < 0)
				return;

			switch(tool)
			{
			case EditorTool.Frame:
				{
					frameStart.X = mouse.X;
					frameStart.Y = mouse.Y;
					frameEnd.X = mouse.X;
					frameEnd.Y = mouse.Y;

					numericUpDownFrameX.Value = mouse.X;
					numericUpDownFrameY.Value = mouse.Y;
					numericUpDownFrameWidth.Value = 0;
					numericUpDownFrameHeight.Value = 0;
				}
				break;
			case EditorTool.Collision:
				{
					collisionStart.X = mouse.X;
					collisionStart.Y = mouse.Y;
					collisionEnd.X = mouse.X;
					collisionEnd.Y = mouse.Y;

					numericUpDownCollisionX.Value = mouse.X;
					numericUpDownCollisionY.Value = mouse.Y;
					numericUpDownCollisionWidth.Value = 0;
					numericUpDownCollisionHeight.Value = 0;
				}
				break;
			case EditorTool.Anchor:
				{
					numericUpDownAnchorX.Value = mouse.X;
					numericUpDownAnchorY.Value = mouse.Y;
				}
				break;
			case EditorTool.Point:
				{
					numericUpDownPointX.Value = mouse.X;
					numericUpDownPointY.Value = mouse.Y;
				}
				break;
			}

			if (updateConstantly)
			{
				buttonUpdateFrame_Click(this, new EventArgs());
				graphicsPanelAnimationPreview.Invalidate();
			}

			graphicsPanelSpriteSheet.Invalidate();
		}

		private void graphicsPanelSpriteSheet_MouseMove(object sender, MouseEventArgs e)
		{
			if (spriteSheet == null)
				return;

			if (e.Button != System.Windows.Forms.MouseButtons.Left)
				return;

			System.Drawing.Point read = new System.Drawing.Point(0, 0);
			read.X += graphicsPanelSpriteSheet.AutoScrollPosition.X;
			read.Y += graphicsPanelSpriteSheet.AutoScrollPosition.Y;

			Point mouse = new Point(
				(int)((e.X - read.X) / currentZoom),
				(int)((e.Y - read.Y) / currentZoom));

			if (mouse.X < 0 || mouse.Y < 0)
				return;

			switch(tool)
			{
			case EditorTool.Frame:
				{
					frameEnd.X = mouse.X;
					frameEnd.Y = mouse.Y;

					if (frameStart.X < frameEnd.X && frameStart.Y < frameEnd.Y)
					{
						numericUpDownFrameX.Value = frameStart.X;
						numericUpDownFrameY.Value = frameStart.Y;
						numericUpDownFrameWidth.Value = frameEnd.X - frameStart.X;
						numericUpDownFrameHeight.Value = frameEnd.Y - frameStart.Y;
					}
					else if (frameStart.X > frameEnd.X && frameStart.Y > frameEnd.Y)
					{
						numericUpDownFrameX.Value = frameEnd.X;
						numericUpDownFrameY.Value = frameEnd.Y;
						numericUpDownFrameWidth.Value = frameStart.X - frameEnd.X;
						numericUpDownFrameHeight.Value = frameStart.Y - frameEnd.Y;
					}
					else if (frameStart.X < frameEnd.X)
					{
						numericUpDownFrameX.Value = frameStart.X;
						numericUpDownFrameY.Value = frameEnd.Y;
						numericUpDownFrameWidth.Value = frameEnd.X - frameStart.X;
						numericUpDownFrameHeight.Value = frameStart.Y - frameEnd.Y;
					}
					else if (frameStart.X > frameEnd.X)
					{
						numericUpDownFrameX.Value = frameEnd.X;
						numericUpDownFrameY.Value = frameStart.Y;
						numericUpDownFrameWidth.Value = frameStart.X - frameEnd.X;
						numericUpDownFrameHeight.Value = frameEnd.Y - frameStart.Y;
					}
					else
					{
						numericUpDownFrameX.Value = mouse.X;
						numericUpDownFrameY.Value = mouse.Y;
						numericUpDownFrameWidth.Value = 0;
						numericUpDownFrameHeight.Value = 0;
					}

				}
				break;
			case EditorTool.Collision:
				{
					collisionEnd.X = mouse.X;
					collisionEnd.Y = mouse.Y;

					if (collisionStart.X < collisionEnd.X && collisionStart.Y < collisionEnd.Y)
					{
						numericUpDownCollisionX.Value = collisionStart.X;
						numericUpDownCollisionY.Value = collisionStart.Y;
						numericUpDownCollisionWidth.Value = collisionEnd.X - collisionStart.X;
						numericUpDownCollisionHeight.Value = collisionEnd.Y - collisionStart.Y;
					}
					else if (collisionStart.X > collisionEnd.X && collisionStart.Y > collisionEnd.Y)
					{
						numericUpDownCollisionX.Value = collisionEnd.X;
						numericUpDownCollisionY.Value = collisionEnd.Y;
						numericUpDownCollisionWidth.Value = collisionStart.X - collisionEnd.X;
						numericUpDownCollisionHeight.Value = collisionStart.Y - collisionEnd.Y;
					}
					else if (collisionStart.X < collisionEnd.X)
					{
						numericUpDownCollisionX.Value = collisionStart.X;
						numericUpDownCollisionY.Value = collisionEnd.Y;
						numericUpDownCollisionWidth.Value = collisionEnd.X - collisionStart.X;
						numericUpDownCollisionHeight.Value = collisionStart.Y - collisionEnd.Y;
					}
					else if (collisionStart.X > collisionEnd.X)
					{
						numericUpDownCollisionX.Value = collisionEnd.X;
						numericUpDownCollisionY.Value = collisionStart.Y;
						numericUpDownCollisionWidth.Value = collisionStart.X - collisionEnd.X;
						numericUpDownCollisionHeight.Value = collisionEnd.Y - collisionStart.Y;
					}
					else
					{
						numericUpDownCollisionX.Value = mouse.X;
						numericUpDownCollisionY.Value = mouse.Y;
						numericUpDownCollisionWidth.Value = 0;
						numericUpDownCollisionHeight.Value = 0;
					}
				}
				break;
			case EditorTool.Anchor:
				{
					numericUpDownAnchorX.Value = mouse.X;
					numericUpDownAnchorY.Value = mouse.Y;
				}
				break;
			case EditorTool.Point:
				{
					numericUpDownPointX.Value = mouse.X;
					numericUpDownPointY.Value = mouse.Y;
				}
				break;
			}

			if (updateConstantly)
			{
				buttonUpdateFrame_Click(this, new EventArgs());
				graphicsPanelAnimationPreview.Invalidate();
			}

			graphicsPanelSpriteSheet.Invalidate();
		}

		private void buttonAddFrame_Click(object sender, EventArgs e)
		{
			Frame newframe = new Frame();

			newframe.Name = textBoxFrameName.Text;

			newframe.Eventstring = textBoxFrameEvent.Text;

			newframe.Speed = (double)numericUpDownSpeed.Value;

			newframe.FrameRect.X = (int)numericUpDownFrameX.Value;
			newframe.FrameRect.Y = (int)numericUpDownFrameY.Value;
			newframe.FrameRect.Width = (int)numericUpDownFrameWidth.Value;
			newframe.FrameRect.Height = (int)numericUpDownFrameHeight.Value;

			newframe.AnchorPoint.X = (int)numericUpDownAnchorX.Value;
			newframe.AnchorPoint.Y = (int)numericUpDownAnchorY.Value;

			foreach (Rectangle rect in masterListCollision)
			{
				newframe.CollisionRects.Add(new Rectangle(rect.X, rect.Y, rect.Width, rect.Height));
			}

			foreach (Point point in masterListPoints)
			{
				newframe.SpecialPoints.Add(new Point(point.X, point.Y));
			}

			masterListFrames.Add(newframe);

			listBoxFrames.DataSource = null;
			listBoxFrames.DataSource = masterListFrames;

			listBoxFrames.SelectedIndex = listBoxFrames.Items.Count - 1;
		}

		private void buttonRemoveFrame_Click(object sender, EventArgs e)
		{
			if (listBoxFrames.SelectedIndex == -1)
				return;

			masterListFrames.RemoveAt(listBoxFrames.SelectedIndex);

			textBoxFrameName.Text = "DEFAULT";

			textBoxFrameEvent.Text = "";

			numericUpDownSpeed.Value = 0.125m;

			numericUpDownFrameX.Value = 0;
			numericUpDownFrameY.Value = 0;
			numericUpDownFrameWidth.Value = 0;
			numericUpDownFrameHeight.Value = 0;

			numericUpDownAnchorX.Value = 0;
			numericUpDownAnchorY.Value = 0;

			numericUpDownCollisionX.Value = 0;
			numericUpDownCollisionY.Value = 0;
			numericUpDownCollisionWidth.Value = 0;
			numericUpDownCollisionHeight.Value = 0;

			masterListCollision.Clear();
			listBoxCollision.DataSource = null;
			listBoxCollision.DataSource = masterListCollision;

			numericUpDownPointX.Value = 0;
			numericUpDownPointY.Value = 0;

			masterListPoints.Clear();
			listBoxPoints.DataSource = null;
			listBoxPoints.DataSource = masterListPoints;


			listBoxFrames.DataSource = null;
			listBoxFrames.DataSource = masterListFrames;

			listBoxFrames.SelectedIndex = -1;
		}

		private void buttonUpdateFrame_Click(object sender, EventArgs e)
		{
			if (listBoxFrames.SelectedIndex == -1)
				return;

			masterListFrames[listBoxFrames.SelectedIndex].Name = textBoxFrameName.Text;

			masterListFrames[listBoxFrames.SelectedIndex].Eventstring = textBoxFrameEvent.Text;

			masterListFrames[listBoxFrames.SelectedIndex].Speed = (double)numericUpDownSpeed.Value;

			masterListFrames[listBoxFrames.SelectedIndex].FrameRect.X = (int)numericUpDownFrameX.Value;
			masterListFrames[listBoxFrames.SelectedIndex].FrameRect.Y = (int)numericUpDownFrameY.Value;
			masterListFrames[listBoxFrames.SelectedIndex].FrameRect.Width = (int)numericUpDownFrameWidth.Value;
			masterListFrames[listBoxFrames.SelectedIndex].FrameRect.Height = (int)numericUpDownFrameHeight.Value;

			masterListFrames[listBoxFrames.SelectedIndex].AnchorPoint.X = (int)numericUpDownAnchorX.Value;
			masterListFrames[listBoxFrames.SelectedIndex].AnchorPoint.Y = (int)numericUpDownAnchorY.Value;

			masterListFrames[listBoxFrames.SelectedIndex].CollisionRects.Clear();
			foreach (Rectangle rect in masterListCollision)
			{
				masterListFrames[listBoxFrames.SelectedIndex].CollisionRects.Add(new Rectangle(rect.X, rect.Y, rect.Width, rect.Height));
			}

			masterListFrames[listBoxFrames.SelectedIndex].SpecialPoints.Clear();
			foreach (Point point in masterListPoints)
			{
				masterListFrames[listBoxFrames.SelectedIndex].SpecialPoints.Add(new Point(point.X, point.Y));
			}

			graphicsPanelAnimationPreview.AutoScrollMinSize = new System.Drawing.Size(
				(int)numericUpDownFrameWidth.Value + 15, (int)numericUpDownFrameHeight.Value + 15);

			graphicsPanelSpriteSheet.Invalidate();
			graphicsPanelAnimationPreview.Invalidate();
		}

		private void listBoxFrames_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (listBoxFrames.SelectedItem == null)
				return;

			textBoxFrameName.Text = ((Frame)listBoxFrames.SelectedItem).Name;

			textBoxFrameEvent.Text = ((Frame)listBoxFrames.SelectedItem).Eventstring;

			numericUpDownSpeed.Value = (decimal)((Frame)listBoxFrames.SelectedItem).Speed;

			numericUpDownFrameX.Value = (decimal)((Frame)listBoxFrames.SelectedItem).FrameRect.X;
			numericUpDownFrameY.Value = (decimal)((Frame)listBoxFrames.SelectedItem).FrameRect.Y;
			numericUpDownFrameWidth.Value = (decimal)((Frame)listBoxFrames.SelectedItem).FrameRect.Width;
			numericUpDownFrameHeight.Value = (decimal)((Frame)listBoxFrames.SelectedItem).FrameRect.Height;

			numericUpDownAnchorX.Value = (decimal)((Frame)listBoxFrames.SelectedItem).AnchorPoint.X;
			numericUpDownAnchorY.Value = (decimal)((Frame)listBoxFrames.SelectedItem).AnchorPoint.Y;

			masterListCollision.Clear();
			foreach (Rectangle rect in ((Frame)listBoxFrames.SelectedItem).CollisionRects)
			{
				masterListCollision.Add(rect);
			}
			listBoxCollision.DataSource = null;
			listBoxCollision.DataSource = masterListCollision;

			masterListPoints.Clear();
			foreach (Point point in ((Frame)listBoxFrames.SelectedItem).SpecialPoints)
			{
				masterListPoints.Add(point);
			}
			listBoxPoints.DataSource = null;
			listBoxPoints.DataSource = masterListPoints;

			graphicsPanelAnimationPreview.AutoScrollMinSize = new System.Drawing.Size(
				(int)numericUpDownFrameWidth.Value + 15, (int)numericUpDownFrameHeight.Value + 15);

			graphicsPanelSpriteSheet.Invalidate();
			graphicsPanelAnimationPreview.Invalidate();
		}

		private void buttonCollisionAdd_Click(object sender, EventArgs e)
		{
			Rectangle rect = new Rectangle();

			rect.X = (int)numericUpDownCollisionX.Value;
			rect.Y = (int)numericUpDownCollisionY.Value;
			rect.Width = (int)numericUpDownCollisionWidth.Value;
			rect.Height = (int)numericUpDownCollisionHeight.Value;

			masterListCollision.Add(rect);
			listBoxCollision.DataSource = null;
			listBoxCollision.DataSource = masterListCollision;
		}

		private void buttonCollisionRemove_Click(object sender, EventArgs e)
		{
			if (listBoxCollision.SelectedIndex == -1)
				return;

			masterListCollision.RemoveAt(listBoxCollision.SelectedIndex);
			listBoxCollision.DataSource = null;
			listBoxCollision.DataSource = masterListCollision;

			listBoxCollision.SelectedIndex = -1;

			graphicsPanelSpriteSheet.Invalidate();
		}

		private void buttonCollisionUpdate_Click(object sender, EventArgs e)
		{
			if (listBoxCollision.SelectedIndex == -1)
				return;

			Rectangle rect = masterListCollision[listBoxCollision.SelectedIndex];

			rect.X = (int)numericUpDownCollisionX.Value;
			rect.Y = (int)numericUpDownCollisionY.Value;
			rect.Width = (int)numericUpDownCollisionWidth.Value;
			rect.Height = (int)numericUpDownCollisionHeight.Value;

			listBoxCollision.DataSource = null;
			listBoxCollision.DataSource = masterListCollision;

			graphicsPanelSpriteSheet.Invalidate();
		}

		private void listBoxCollision_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (listBoxCollision.SelectedItem == null)
				return;

			numericUpDownCollisionX.Value = ((Rectangle)listBoxCollision.SelectedItem).X;
			numericUpDownCollisionY.Value = ((Rectangle)listBoxCollision.SelectedItem).Y;
			numericUpDownCollisionWidth.Value = ((Rectangle)listBoxCollision.SelectedItem).Width;
			numericUpDownCollisionHeight.Value = ((Rectangle)listBoxCollision.SelectedItem).Height;


			graphicsPanelSpriteSheet.Invalidate();
		}

		private void buttonPointAdd_Click(object sender, EventArgs e)
		{
			Point point = new Point();

			point.X = (int)numericUpDownPointX.Value;
			point.Y = (int)numericUpDownPointY.Value;

			masterListPoints.Add(point);
			listBoxPoints.DataSource = null;
			listBoxPoints.DataSource = masterListPoints;
		}

		private void buttonPointRemove_Click(object sender, EventArgs e)
		{
			if (listBoxPoints.SelectedIndex == -1)
				return;

			masterListPoints.RemoveAt(listBoxPoints.SelectedIndex);
			listBoxPoints.DataSource = null;
			listBoxPoints.DataSource = masterListPoints;

			listBoxPoints.SelectedIndex = -1;

			graphicsPanelSpriteSheet.Invalidate();
		}

		private void buttonPointUpdate_Click(object sender, EventArgs e)
		{
			if (listBoxPoints.SelectedIndex == -1)
				return;

			Point point = masterListPoints[listBoxPoints.SelectedIndex];

			point.X = (int)numericUpDownPointX.Value;
			point.Y = (int)numericUpDownPointY.Value;

			listBoxPoints.DataSource = null;
			listBoxPoints.DataSource = masterListPoints;

			graphicsPanelSpriteSheet.Invalidate();
		}

		private void listBoxPoints_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (listBoxPoints.SelectedItem == null)
				return;

			numericUpDownPointX.Value = ((Point)listBoxPoints.SelectedItem).X;
			numericUpDownPointY.Value = ((Point)listBoxPoints.SelectedItem).Y;

			graphicsPanelSpriteSheet.Invalidate();
		}

		private void buttonNextFrame_Click(object sender, EventArgs e)
		{
			if (listBoxFrames.Items.Count == 0)
				return;

			if (listBoxFrames.SelectedIndex + 1 >= listBoxFrames.Items.Count)
			{
				listBoxFrames.SelectedIndex = 0;
			}
			else
			{
				listBoxFrames.SelectedIndex++;
			}
		}

		private void buttonPrevFrame_Click(object sender, EventArgs e)
		{
			if (listBoxFrames.Items.Count == 0)
				return;

			if (listBoxFrames.SelectedIndex - 1 < 0)
			{
				listBoxFrames.SelectedIndex = listBoxFrames.Items.Count - 1;
			}
			else
			{
				listBoxFrames.SelectedIndex--;
			}
		}

		private void buttonPlay_Click(object sender, EventArgs e)
		{
			if (listBoxFrames.SelectedIndex == -1)
				listBoxFrames.SelectedIndex = 0;

			timerPlay.Interval = (int)(((Frame)listBoxFrames.SelectedItem).Speed * 1000);
			timerPlay.Start();
		}

		private void timerPlay_Tick(object sender, EventArgs e)
		{
			buttonNextFrame_Click(this, new EventArgs());

			timerPlay.Interval = (int)(((Frame)listBoxFrames.SelectedItem).Speed * 1000);
		}

		private void buttonStop_Click(object sender, EventArgs e)
		{
			timerPlay.Stop();
		}

		private void toolStripComboBoxZoom_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (spriteSheet == null)
				return;

			currentZoom = int.Parse((string)toolStripComboBoxZoom.SelectedItem) / 100f;

			spriteSheetScale = ScaleImage(spriteSheet, currentZoom);

			graphicsPanelSpriteSheet.AutoScrollMinSize = new Size(
					spriteSheetScale.Width + 15, spriteSheetScale.Height + 15);

			graphicsPanelSpriteSheet.Invalidate();
		}

	}
}
